package com.lzy.wzy.service.imp;

import com.lzy.wzy.constant.MyConstant;
import com.lzy.wzy.mapper.UserMapper;
import com.lzy.wzy.mapper.WorkMapper;
import com.lzy.wzy.model.UserPartBean;
import com.lzy.wzy.result.Response;
import com.lzy.wzy.result.ResponseCode;
import com.lzy.wzy.result.Result;
import com.lzy.wzy.service.MyFlowableService;
import com.lzy.wzy.token.MyUsernamePasswordToken;
import com.lzy.wzy.utils.PatternUtils;
import com.lzy.wzy.vo.ApprovalDetailsVo;
import com.lzy.wzy.vo.WorkOrderTaskVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.flowable.engine.IdentityService;
import org.flowable.engine.TaskService;
import org.flowable.idm.api.User;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MyFlowableServiceImp implements MyFlowableService {

    @Autowired
    private WorkMapper workMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TaskService taskService;


    @Autowired
    private IdentityService identityService;

    /*
     * @Author wzy
     * @Description //TODO 审批通过
     * @Date 2021/8/20 17:29
     * @Param * @param: taskId 任务id
     * @param: workOrderNumber 工单号
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doApprove(String taskId, String workOrderNumber) {
        Task task = verifyTicketStatus(workOrderNumber, taskId);
        if (task == null) {
            return Result.failure("审批失败");
        }
        //获取 key
        String taskKey = task.getTaskDefinitionKey();

        Map<String, Object> map = new HashMap<>();
        map.put("result", true);
        map.put("key", taskKey);
        map.put("workOrderNumber",workOrderNumber);
        //完成任务
        taskService.complete(taskId, map);
        log.info("批准通过");
        return Result.success("审批成功");
    }


    private Task verifyTicketStatus(String workOrderNumber, String taskId) {
        String status = workMapper.getWorkOrderStatus(workOrderNumber);
        if (MyConstant.WorkOrderStatus.InSystem.equals(status)
                || MyConstant.WorkOrderStatus.FINISHED.equals(status)) {
            MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
            String userId = (String) token.getPrincipal();
            return taskService.createTaskQuery().taskAssignee(userId).taskId(taskId).singleResult();
        } else {
            return null;
        }
    }

    /*
     * @Author wzy
     * @Description //TODO 审批不通过
     * @Date 2021/8/20 17:32
     * @Param * @param: taskId 任务id
     * @param: workOrderNumber 工单号
     * @param: reason 不通过原因
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doReject(String taskId, String workOrderNumber) {
        Task task = verifyTicketStatus(workOrderNumber, taskId);
        if (task == null) {
            return Result.failure("审批失败");
        }
        //获取 key
        String taskKey = task.getTaskDefinitionKey();
        Map<String, Object> map = new HashMap<>();
        map.put("result", false);
        map.put("key", taskKey);
        map.put("workOrderNumber",workOrderNumber);
        taskService.complete(taskId, map);
        return Result.success("驳回成功");
    }


    @Override
    public List<WorkOrderTaskVo> doGetAnAgentTask(String userId,int pageNum,int pageSize) {
        List<WorkOrderTaskVo> task = userMapper.getHiApprove(userId,pageNum,pageSize);
        for (WorkOrderTaskVo taskVo : task) {
            switch (taskVo.getStatus()) {
                case MyConstant.ApproveStatus.MODERATED:
                    taskVo.setImg("/image/pend.png");
                    break;
                case MyConstant.ApproveStatus.UNDER_REVIEW:
                    taskVo.setImg("/image/under-review.png");
                    break;
                case MyConstant.ApproveStatus.EXAMINATION_PASSED:
                    taskVo.setImg("/image/tp2.png");
                    break;
                case MyConstant.ApproveStatus.REVIEW_REJECTED:
                    taskVo.setImg("/image/bh.png");
            }
        }
        return task;
    }

    @Override
    public Result<ApprovalDetailsVo> doGetApproveDetails(String proInstId) {
        ApprovalDetailsVo approvalDetailsVo = userMapper.queryApproveDetails(proInstId);
        switch (approvalDetailsVo.getApproveStatus()) {
            case MyConstant.ApproveStatus.MODERATED:
                approvalDetailsVo.setImg("/image/pend.png");
                break;
            case MyConstant.ApproveStatus.UNDER_REVIEW:
                approvalDetailsVo.setImg("/image/under-review.png");
                break;
            case MyConstant.ApproveStatus.EXAMINATION_PASSED:
                approvalDetailsVo.setImg("/image/tp2.png");
                break;
            case MyConstant.ApproveStatus.REVIEW_REJECTED:
                approvalDetailsVo.setImg("/image/bh.png");
        }
        List<User> list = identityService.createUserQuery().memberOfGroups(MyConstant.ApproveGroup.groups).list();
        Map<String, List<User>> collect = list.stream().collect(Collectors.groupingBy(User::getTenantId));
        for (Map.Entry<String, List<User>> entry : collect.entrySet()) {
            switch (entry.getKey()) {
                case "16":
                    approvalDetailsVo.setPlNames(join(entry.getValue()));
                    break;
                case "17":
                    approvalDetailsVo.setQlNames(join(entry.getValue()));
                    break;
                case "26":
                    approvalDetailsVo.setCraNames(join(entry.getValue()));
                    break;
                case "28":
                    approvalDetailsVo.setPsNames(join(entry.getValue()));
                    break;
                case "2":
                    approvalDetailsVo.setPlanNames(join(entry.getValue()));
                    break;
            }
        }

        return Result.success(approvalDetailsVo);
    }

    private String join(List<User> list){
        String suffix="";
        if (list.size()>3) {
            list=list.subList(0,2);
            suffix="...";
        }
        return list.stream().map(User::getFirstName).collect(Collectors.joining(","))+suffix;
    }

}
